﻿/* Glittering Stars Effect with HTML5 Canvas and JavaScript
 * 
 * Repository: https://code.google.com/p/glittering-stars-effect/
 * Licensed under GNU GPL v3
 * Contact: galya.bogdanova@yahoo.com
 */

// SETTINGS starts

// ID of the canvas where the stars will appear
canvasID = 'background_canvas';
// sizes of the canvas
canvasWidth = window.innerWidth;
canvasHeight = window.innerHeight;
// how often the fade effect will update in milliseconds
fadeEffectInterval = 150;
// how often a new star will appear in milliseconds
newStarInterval = 1000;
// how often an old star will be replaced in milliseconds
replaceStarInterval = 5000;
// ID of the div where you don't need stars
mainContentDiv = 'wrapper';
// max number of stars at the same time
maxGlitters = 10;
// size, weight and number of rays of the long rays of stars
longRaysSize = 15;
longRaysNumber = 4;
longRaysWeight = 0.1;
// size, weight and number of rays of the short rays of stars
shortRaysSize = 10;
shortRaysNumber = 8;
shortRaysWeight = 0.1;

// SETTINGS ends

// DO NOT MAKE CHANGES BELOW

function canvasCreator() {
    canvas = document.getElementById(canvasID);

    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    ctx = canvas.getContext("2d");

    arrayGlitteringObjects = [];

    setInterval(updateCanvas, fadeEffectInterval);
    setInterval(glitterCreate, newStarInterval);
    setInterval(glitterDelete, replaceStarInterval);
}

function updateCanvas() {
    ctx.clearRect(canvas.offsetTop, canvas.offsetLeft, canvas.offsetWidth, canvas.offsetHeight);
    glitterUpdate();
}

function glitterCreate() {
    if (arrayGlitteringObjects.length < maxGlitters) {
        arrayGlitteringObjects.push(new glitteringObject());
    }
}

function glitterDelete() {
    arrayGlitteringObjects.splice(0, 1);
}

function glitterUpdate() {
    for (var index in arrayGlitteringObjects) {
        ctx.fillStyle = arrayGlitteringObjects[index].fillColor;

        ctx.globalAlpha = arrayGlitteringObjects[index].opacity;
        
        if (arrayGlitteringObjects[index].isOpacityLowering) {
            if (arrayGlitteringObjects[index].opacity > 0.1) {
                arrayGlitteringObjects[index].opacity -= 0.1;
            }
            else {
                arrayGlitteringObjects[index].isOpacityLowering = false;
            }
        }
        else {
            if (arrayGlitteringObjects[index].opacity < 1) {
                arrayGlitteringObjects[index].opacity += 0.1;
            }
            else {
                arrayGlitteringObjects[index].isOpacityLowering = true;
            }
        }

        var x = arrayGlitteringObjects[index].coordinates["x"];
        var y = arrayGlitteringObjects[index].coordinates["y"];


        // draws the big rays of the star
        var size = arrayGlitteringObjects[index].size;
        var starWeight = longRaysWeight;
        var numberRays = longRaysNumber;

        ctx.save();
        ctx.beginPath();
        ctx.translate(x, y);
        ctx.moveTo(0, 0 - size);
        for (var i = 0; i < numberRays; i++) {
            ctx.rotate(Math.PI / numberRays);
            ctx.lineTo(0, 0 - (size * starWeight));
            ctx.rotate(Math.PI / numberRays);
            ctx.lineTo(0, 0 - size);
        }
        ctx.fill();
        ctx.restore();


        // draws the small rays of the star
        size = shortRaysSize;
        starWeight = shortRaysWeight;
        numberRays = shortRaysNumber;

        ctx.save();
        ctx.beginPath();
        ctx.translate(x, y);
        ctx.moveTo(0, 0 - size);
        for (i = 0; i < numberRays; i++) {
            ctx.rotate(Math.PI / numberRays);
            ctx.lineTo(0, 0 - (size * starWeight));
            ctx.rotate(Math.PI / numberRays);
            ctx.lineTo(0, 0 - size);
        }
        ctx.fill();
        ctx.restore();

        // draws circle in the center of the star
        ctx.fillStyle = '#fff';
        ctx.beginPath();
        ctx.arc(x, y, 3, 0, 2 * Math.PI);
        ctx.fill();
    }
}

function glitteringObject() {
    this.size = longRaysSize;
    this.width = this.size;
    this.height = this.size;
    this.fillColor = getRandomColor();

    this.coordinates = getRandomCoordinates(this.width, this.height);
    
    // div #wrapper rectangle
    var contentDiv = document.getElementById(mainContentDiv);

    var contentDivX1 = contentDiv.offsetLeft;
    var contentDivX2 = contentDiv.offsetLeft + contentDiv.offsetWidth;
    var contentDivY1 = contentDiv.offsetTop;
    var contentDivY2 = contentDiv.offsetTop + contentDiv.offsetHeight;

    this.coordinates = getRandomCoordinates(this.width, this.height);

    // checks if the position of the star is in the #wrapper
    // if so, gets new position
    this.coordinates = getRandomCoordinates(this.width, this.height);

    var isInContentDiv = false;
    if (contentDivX1 <= this.coordinates["x"] <= contentDivX2 && contentDivY1 <= this.coordinates["y"] <= contentDivY2)
    {
        isInContentDiv = true;
    }

    while (isInContentDiv) {
        this.coordinates = getRandomCoordinates(this.width, this.height);
        if (this.coordinates["x"] < contentDivX1 || contentDivX2 < this.coordinates["x"] || this.coordinates["y"] < contentDivY1 || contentDivY2 < this.coordinates["y"])
        {
            isInContentDiv = false;
            break;
        }
    }

    this.opacity = 1;
    this.isOpacityLowering = true;
}

function getRandomCoordinates(objWidth, objHeight) {
    var x = Math.round(Math.random() * (canvas.width - objWidth));
    var y = Math.round(Math.random() * (canvas.height - objHeight));
    return { "x": x, "y": y };
}

function getRandomColor() {
    var red = Math.round(Math.random() * 255);
    var green = Math.round(Math.random() * 255);
    var blue = Math.round(Math.random() * 255);

    return "rgb(" + red + "," + green + "," + blue + ")";
}

window.addEventListener("load", canvasCreator, false);